// 存储DKS 端机发送的数据的结构体
// Created by li on 24-6-17.
//

#ifndef DKS_AGX_STRUCT_DEFINE_H
#define DKS_AGX_STRUCT_DEFINE_H

#include <cstdint>
#include <iomanip>
#include <atomic>
#include <map>
#include <mutex>
using namespace std;
enum RECV_TYPE{others, agx_send_visual_inertial_nav_type, px4_transmit2pod_pod_control_type, agx_2_px4_route_type};

#pragma pack(push,1)
typedef struct{
    uint8_t 	 node_id ;	//  定义消息来源节点 , 单位:  0x01—0xA0
    uint32_t 	 navigation_package_count ;	//  导航数据导航包计数 , 单位:  1
    uint8_t 	 navigation_status ;	//  0x11：视觉-惯性组合导航 0x22：纯惯性导航 0x33：导航系统异常 , 单位:  0xXX
    int32_t 	 longitude ;	//  地球坐标系 , 单位:  1e-7°
    int32_t 	 latitude ;	//  nan , 单位:  1e-7°
    int32_t 	 height ;	//  nan , 单位:  1e-4m
    int32_t 	 roll_rate ;	//  弹体坐标系 , 单位:  0.0001°/s
    int32_t 	 pitch_rate ;	//  nan , 单位:  0.0001°/s
    int32_t 	 yaw_rate ;	//  nan , 单位:  0.0001°/s
    int32_t 	 roll_angle ;	//  弹体坐标系与地理坐标系间形成的姿态角 , 单位:  0.0001°
    int32_t 	 pitch_angle ;	//  nan , 单位:  0.0001°
    uint32_t 	 yaw_angle ;	//  nan , 单位:  0.0001°
    int16_t 	 east_velocity ;	//  地理坐标系 , 单位:  0.01m/s
    int16_t 	 north_velocity ;	//  nan , 单位:  0.01m/s
    int16_t 	 celestial_velocity ;	//  nan , 单位:  0.01m/s
    int16_t 	 resultant_velocity ;	//  nan , 单位:  0.01m/s
    int32_t 	 ax ;	//  不包含地球引力加速度的绝对加速度值在弹体坐标系下的投影分量 , 单位:  0.0001m/s²
    int32_t 	 ay ;	//  nan , 单位:  0.0001m/s²
    int32_t 	 az ;	//  nan , 单位:  0.0001m/s²
    uint8_t 	 self_check ;	//  0x11:自检开始 0x22:自检未通过 0x33:自检通过 0x44:开始对准 0x55:对准未完成 0x66:对准完成 , 单位:  0xXX
}agx_send_visual_inertial_nav_package_t;
#pragma pack(pop)


#pragma pack(push,1)
typedef struct{
    uint8_t 	 results_of_route_setting ;	//  nan , 单位:  0x00：默认未重新规划 0x01：本包航路校验通过 0x02：本次航路校验通过
    //其他为异常状态字：（十进制）暂定 10：航路点总数值不符合要求 11：航路点总数值与实际航路点个数不一致 12：航路点序号值超出航路点总数
    //13：航路点序号值与实际航路点序号不一致 14：航路点经纬高均为0 15：航路点经纬高超出范围 16：相邻航路点距离不符合要求 22：转弯角度不符合要求
    uint8_t 	 reservation1 ;	//  nan , 单位:  0x00
    uint8_t 	 reservation2 ;	//  nan , 单位:  0x00
    uint8_t 	 reservation3 ;	//  nan , 单位:  0x00
}agx_recv_route_fdbk_package_t;
#pragma pack(pop)


#pragma pack(push,1)
typedef struct{
    uint8_t 	 node_id ;	//  nan , 单位:  1-240
    uint32_t 	 flight_time ;	//  导航数据导航包计数 , 单位:  1ms
    uint8_t 	 navigation_status ;	//  0x11：纯惯性导航 0x22：组合导航 0x33：视觉导航 0x44：AI导航 , 单位:  0xXX
    int32_t 	 longitude ;	//  地球坐标系 , 单位:  1e-7°
    int32_t 	 latitude ;	//  nan , 单位:  1e-7°
    int32_t 	 height ;	//  nan , 单位:  1e-4m
    int16_t 	 east_velocity ;	//  东北天坐标系 , 单位:  0.01m/s
    int16_t 	 north_velocity ;	//  nan , 单位:  0.01m/s
    int16_t 	 celestial_velocity ;	//  nan , 单位:  0.01m/s
    int16_t 	 roll_angle ;	//  弹体坐标系与东北天坐标系间形成的姿态角 , 单位:  0.01°
    int16_t 	 pitch_angle ;	//  nan , 单位:  0.01°
    uint16_t 	 yaw_angle ;	//  nan , 单位:  0.01°
    int16_t 	 roll_rate ;	//  弹体坐标系 , 单位:  0.01°/s
    int16_t 	 pitch_rate ;	//  nan , 单位:  0.01°/s
    int16_t 	 yaw_rate ;	//  nan , 单位:  0.01°/s
    int16_t 	 ax ;	//  不包含地球引力加速度的绝对加速度值在弹体坐标系下的投影分量 , 单位:  0.01m/s²
    int16_t 	 ay ;	//  nan , 单位:  0.01m/s²
    int16_t 	 az ;	//  nan , 单位:  0.01m/s²
    uint16_t 	 total_number_of_waypoints ;	//  nan , 单位:  1
    uint16_t 	 current_waypoint_serial_number ;	//  nan , 单位:  1
    uint16_t 	 total_fuel_consumption ;	//  nan , 单位:  1.23
    int16_t 	 reservation1 ;	//  nan , 单位:  nan
    int16_t 	 reservation2 ;	//  nan , 单位:  nan
    uint8_t 	 self_check ;	//  0x11：自检开始 0x22：自检未通过 0x33：自检通过 0x44：开始对准 0x55：对准未完成 0x66：对准完成 , 单位:  0xXX
}px4_send_navinfo_t;
#pragma pack(pop)


#pragma pack(push,1)
typedef struct{
    uint8_t 	 pod_control ;	//  0x2d：打开激光测距 0x26：指定框架角 0x24：云台搜索 0x0D：指点跟踪（x,y坐标） 0x0E：停止跟踪 , 单位:  0xXX
    int16_t 	 pod_parameter_x ;	//  云台搜索时，方位转速0.1deg /s; 指定框架角时，方位角 , 单位:  0.01deg
    int16_t 	 pod_parameter_y ;	//  云台搜索时，俯仰转速  0.1deg /s ; 指定框架角时，俯仰角 0.01deg
    uint8_t 	 reservations_1 ;	//  nan , 单位:  nan
    uint8_t 	 reservation2 ;	//  nan , 单位:  nan
}px4_transmit2pod_pod_control_t;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct{
    uint8_t 	 pod_status ;	//  0x11：吊舱自主 0x22：吊舱云台搜索 0x33：吊舱指定框架角 0x44：目标跟踪 , 单位:  0xXX
    int16_t 	 pitch_frame_angle ;	//  云台俯仰角 , 单位:  0.01°
    int16_t 	 yaw_frame_angle ;	//  云台偏航角 , 单位:  0.01°
    int16_t 	 image_tracking_deviation_x ;	//  图像跟踪偏差量x , 单位:  1p
    int16_t 	 image_tracking_deviation_y ;	//  图像跟踪偏差量y , 单位:  1p
    int16_t 	 laser_ranging;	//  0为无效 , 单位:  0.1m
    int16_t 	 reservation1 ;	//  nan , 单位:  nan
    int16_t 	 reservation2 ;	//  nan , 单位:  nan
}px4_transmit2agx_pod_status_t;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct{
    uint16_t 	 flight_waypoint_serial_number ;	//  航路点0为起飞点，最后为目标点 , 单位:  0～65535
    uint8_t 	 number_of_cycles ;	//  nan , 单位:  1～100
    int32_t 	 waypoint_longitude ;	//  nan , 单位:  0.0000001
    int32_t 	 waypoint_latitude ;	//  nan , 单位:  0.0000001
    int32_t 	 waypoint_altitude ;	//  nan , 单位:  0.0001
    uint8_t 	 altitude_attribute ;	//  0：缺省（大地高度） 1：大地高度 2：相对高度 , 单位:  nan
    uint8_t 	 dynamic_properties ;	//  0：缺省（速度指令） 1：速度指令（m/s） 2：转速指令（r/min） 3：到达时间(s) , 单位:  nan
    uint16_t 	 dynamic_value ;	//  速度指令（m/s） 转速指令（r/min） 到达时间(s) , 单位:  1
    uint8_t 	 max_roll_angle ;	//  航路点：最大滚转默认30° 目标点：表示设定落角值 , 单位:  15～60
    uint8_t 	 turning_mode ;	//  航路点：0 快速转弯（默认） 航路点：1 自适应转弯 目标点：0无落角要求 目标点：1设定落角值 , 单位:  nan
    uint8_t 	 control_set_up_backup ;	//  nan , 单位:  nan
}agx_2px4_route_single_t;
#pragma pack(pop)

#pragma pack(push,1)
typedef struct{
    uint8_t 	 target_id = 1 ;	//  nan , 单位:  nan
    uint32_t 	 data_link_time ;	//  ms , 单位:  nan
    uint8_t 	 reservation_attribute[7] ;	//  nan , 单位:  nan
    uint16_t 	 replanning_times ;	//  发完一次航迹规划所有包数据为一次，如1500个航迹点，分三次发送，该字节都为1 , 单位:  1～65535
    uint8_t 	 remaining_packages_in_this_planning ;	//  包数递减，例如1500个航迹点，该字节为3,2,1 , 单位:  1～255
    uint16_t 	 total_number_of_waypoints_in_this_package ;	//  n不超过500 , 单位:  1～500
    agx_2px4_route_single_t routes[50]{};
}ROUTE_INFO;
#pragma pack(pop)



// 枚举类型用于控制AGX发送过来的数据的解包过程，AGX发出
typedef enum {
    AGX_DECODE_HEAD1 = 0,
    AGX_DECODE_HEAD2,
    AGX_PAYLOAD_LEN_H,
    AGX_PAYLOAD_LEN_L,
    AGX_DECODE_MSGID,
    AGX_DECODE_PAYLOAD,
    AGX_DECODE_CHECKSUM_L,      // 校验和低位
} agx_decode_state_t;



struct UDP_RECV_PACK{
    uint16_t length_path=0; //解包时传入，用于获取包长度, route_point_num = (udp_recv_pack.length_path - 19)/22;
    agx_send_visual_inertial_nav_package_t agx_send_visual_inertial_nav_package{};
    px4_transmit2pod_pod_control_t px4_transmit2pod_pod_control_package{};
    uint8_t actual_rout_num = 0;
    agx_2px4_route_single_t routes[500];
};

struct AGX_2UAV_INFO_PACK{
    uint8_t id=0;
    UDP_RECV_PACK udp_recv_pack{};
    atomic<bool> updated_agx_send_visual_inertial_nav = false;
    atomic<bool> updated_px4_transmit2pod_pod_control= false;
    atomic<bool> updated_agx_2px4_routes = false;
    atomic<bool> updated_route_check = false;
    atomic<int> route_send_count = -1; //-1 代表未发送，要先发送 mavlink_message_cnt, mavlink sendFunc read; mavlink_receive_func write
    mutex info_pack_mutex;
    uint8_t route_check_result = 0;

};

#define  AGX_SEND_VISUAL_INERTIAL_NAV_PACKAGE_SIZE 	 sizeof(agx_send_visual_inertial_nav_package_t)
#define  AGX_RECV_ROUTE_FDBK_PACKAGE_SIZE 	 sizeof(agx_recv_route_fdbk_package_t)
#define  PX4_SEND_NAVINFO_SIZE 	 sizeof(px4_send_navinfo_t)
#define  PX4_TRANSMIT2POD_POD_CONTROL_SIZE 	 sizeof(px4_transmit2pod_pod_control_t)
#define  PX4_TRANSMIT2AGX_POD_STATUS_SIZE 	 sizeof(px4_transmit2agx_pod_status_t )
#define  AGX_2PX4_ROUTE_SINGLE_SIZE    sizeof(agx_2px4_route_single_t)

#endif //DKS_AGX_STRUCT_DEFINE_H
